package campus.evip;

import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;

public class XalanUtils {

	/**
	 * Validates XML using the schema definitions inside the XML
	 */
	public static Node validate (String xmlFile, String schemaFile) throws Exception {
	   return validate (new File (xmlFile), new File (schemaFile));
	   }
	
	/**
	 * Validates XML using the schema definitions inside the XML
	 */
	public static Node validate (File xmlFile, File schemaFile) throws Exception {
	   System.setProperty ("javax.xml.parsers.DocumentBuilderFactory", "org.apache.xerces.jaxp.DocumentBuilderFactoryImpl");
	   DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance ();
	   factory.setNamespaceAware (true); 
	   factory.setValidating (true); 
	   factory.setAttribute ("http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema");
	   factory.setAttribute ("http://java.sun.com/xml/jaxp/properties/schemaSource", schemaFile.toURI ().toString ());
	   DocumentBuilder parser = factory.newDocumentBuilder ();
	   final ArrayList<SAXException> exceptions = new ArrayList<SAXException> ();
       parser.setErrorHandler (new DefaultHandler () {
    	   public void error (SAXParseException ex) throws SAXException {
    		  exceptions.add (ex);
    	      }     
    	   public void fatalError(SAXParseException ex) throws SAXException {
     		  exceptions.add (ex);
    	      }		    
    	   public void warning (SAXParseException ex) throws SAXException { }	 
	       });
        FileInputStream fis = new FileInputStream (xmlFile);
        parser.parse (new InputSource (fis));
        fis.close ();
 	    DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance ();
	    DocumentBuilder builder = dbFactory.newDocumentBuilder ();
        Document doc = builder.newDocument ();
        Element root = doc.createElement ("parse-result");
        doc.appendChild (root);
        for (SAXException ex : exceptions) {
        	System.out.println (ex);
        	Element exElement = doc.createElement ("error");
        	exElement.setAttribute ("localized-message", ex.getLocalizedMessage ());
        	exElement.setAttribute ("message", ex.getMessage ());
        	exElement.setAttribute ("message", ex.getMessage ());
        	root.appendChild (exElement);        	
            }
        return doc;
	    }
	
	/**
	 * Lists all files from the starting Directory in XML
	 */
	public static Node getFilesAsXML (String baseDir) throws Exception {
	   return getFilesAsXML (new File (baseDir));		
	   }
	
	/**
	 * Lists all files from the starting Directory in XML
	 */
	public static Node getFilesAsXML (File baseDir) throws Exception {
	   DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance ();
	   DocumentBuilder builder = dbFactory.newDocumentBuilder ();
       Document doc = builder.newDocument ();
       addFiles (baseDir, baseDir, doc, null);
	   return doc;
	   }
	
	private static void addFiles (File baseDir, File dir, Document doc, Node root) throws Exception {
	   if (dir.getName ().equals (".svn") || dir.getName ().equals (".cvs"))
		  return;
	   Element dirNode = doc.createElement ("dir");
	   dirNode.setAttribute ("name", dir.getName ());
	   if (root == null) doc.appendChild (dirNode);
	      else root.appendChild (dirNode);
	   File[] files = dir.listFiles ();
	   if (files == null) return;
	   for (File f : files)
		   if (f.isDirectory ())
			  addFiles (baseDir, f, doc, dirNode);
		      else {
		    	   Element file = doc.createElement ("file");
		    	   file.setAttribute ("name", f.getName ());
		    	   file.setAttribute ("size", ""+f.length ());
		    	   file.setAttribute ("full-path", f.getAbsolutePath ().substring (baseDir.getAbsolutePath ().length ()+1).replace (File.separatorChar, '/'));
		    	   dirNode.appendChild (file);
		           }
	   }
	
    public static void main (String[] argv) throws Exception {
       System.out.println (validate (new File ("c:\\campus\\evip\\export\\output\\virtualpatientdata.xml"), new File ("c:\\campus\\evip\\export\\output\\virtualpatientdata.xsd")).getChildNodes().item(0).getChildNodes().getLength());
       }
	
}